﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using System.Linq;
using EcoSystem.Enums;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace EcoSystem
{
    /// <summary>
    /// 配置模型数据查询类
    /// </summary>
    public class ConfigModelAppService : ApplicationService, IConfigModelAppService
    {
        private readonly IRepository<ConfigDefine, Guid> _defineRepository;
        private readonly IRepository<ConfigSetting, Guid> _repository;
        private readonly IRepository<ConfigCategory, string> _categoryRepository;

        public ConfigModelAppService(
            IRepository<ConfigSetting, Guid> repository,
            IRepository<ConfigDefine, Guid> defineRepository,
            IRepository<ConfigCategory, string> categoryRepository)
        {
            _repository = repository;
            _defineRepository = defineRepository;
            _categoryRepository = categoryRepository;
        }

        public async Task<Dictionary<string, object>> GetAsync(string moduleCode, string category)
        {
            if (!await (await _categoryRepository.GetQueryableAsync()).Where(x => x.Id == moduleCode).AnyAsync())
            {
                return new Dictionary<string, object>();
            }
            //获取分类定义值
            var defineItems = await (await _defineRepository.GetQueryableAsync()).Where(x => x.Category == category).ToListAsync();

            //查询配置数据
            var query = from a in (await _repository.GetQueryableAsync()) select a;
            query = query.Where(x => x.Category == category).Where(x => x.Level == ConfigLevel.G ||
            (x.Level == ConfigLevel.S && x.ModuleCode.Equals(moduleCode)));

            var list = await query.ToListAsync();
            var configValues = new Dictionary<string, object>();
            foreach (var defineItem in defineItems)
            {
                if (configValues.ContainsKey(defineItem.Key)) { continue; }
                var item = list.FirstOrDefault(x => x.Key == defineItem.Key && x.Level == ConfigLevel.S);
                if (item == null)
                {
                    item = list.FirstOrDefault(x => x.Key == defineItem.Key && x.Level == ConfigLevel.G);
                }
                if (item != null)
                {
                    configValues.Add(item.Key, (item.Value));
                }
                else if (!string.IsNullOrEmpty(defineItem.DefaultValue))
                {
                    var defaultValue = JsonConvert.DeserializeObject(defineItem.DefaultValue);
                    configValues.Add(defineItem.Key, defaultValue);
                }
                else
                {
                    configValues.Add(defineItem.Key, GetDefaultValue(defineItem));
                }
            }
            return configValues;
        }

        /// <summary>
        /// 获取指定系统指定分类下的配置数据并返回为指定的数据模型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="moduleCode"></param>
        /// <param name="category"></param>
        /// <returns></returns>
        public async Task<T> GetConfigAsync<T>(string moduleCode, string category) where T : new()
        {
            var dict = await GetAsync(moduleCode, category);
            if (dict != null && dict.Count > 0)
            {
                var json = JsonConvert.SerializeObject(dict);
                return JsonConvert.DeserializeObject<T>(json);
            }
            return await Task.FromResult(default(T));
        }

        /// <summary>
        /// 获取配置定义对应的默认配置值 
        /// </summary>
        /// <param name="define"></param>
        /// <returns></returns>
        private object GetDefaultValue(ConfigDefine define)
        {
            if (!string.IsNullOrEmpty(define.DefaultValue))
            {
                return JsonConvert.DeserializeObject(define.DefaultValue);
            }
            else
            {
                if (define.KeyType == "string")
                {
                    return "";
                }
                else if (define.KeyType == "bool")
                {
                    return false;
                }
                else if (define.KeyType == "number")
                {
                    return 0;
                }
                else if (define.KeyType == "date")
                {
                    return "";
                }
                else if (define.KeyType == "json")
                {
                    return new { };
                }
                else if (define.KeyType == "array")
                {
                    return new object[] { };
                }
                return null;
            }
        }
    }
}
